﻿using System;
using TOOLKIT;
using TOOLKIT.Utils;
using TOOLKIT.Strategies.Drawers;
using TOOLKIT.Strategies.Containers;
using TOOLKIT.Strategies.Behaviors;
using TOOLKIT.Strategies.Observers;


namespace DefaultProject
{
    /// <summary>
    /// This clas extented the Default manager class defining more components
    /// and their strategies
    /// @author khaled tangao - ktangao@gmail.com
    /// </summary>
    public class ApplicationManager : DefaultManager
    {
        /// <summary>
        /// Create a new instance of this class
        /// </summary>
        /// <param name="timer">the timer to use</param>
        /// <param name="nUser">The number of user</param>
        public ApplicationManager(WindowsFrameTimer timer, uint nUser)
            : base(timer, nUser)
        {
            initialize();
        }
        /// <summary>
        /// Create a new instance of this class with only one user
        /// </summary>
        /// <param name="timer">the timer to use</param>
        public ApplicationManager(WindowsFrameTimer timer)
            : base(timer)
        {
            initialize();
        }
        /// <summary>
        /// Define all the components and strategies to apply to them
        /// in the openGl Scene
        /// </summary>
        protected override void initComponents()
        {
            float[] borderColor = { 0.3f, 0.5f, 1.0f, 1.0f };
	        float[] selectedColor = { 0.8f, 0.6f, 0.1f, 1.0f };

            //Give some strategy to the root component
            rootComponent = new VisComponentGL();
            rootComponent.setPosition(400.0f, 300.0f, 0.0f);
            rootComponent.setWidth(400);
            rootComponent.setHeight(300);
            GradientBorderStrategy rootBorder = new GradientBorderStrategy();
            rootBorder.setBorderWidth(-10.0f);
            rootBorder.setColor(borderColor);
            rootComponent.pushStrategy(rootBorder);
            FrictionSurfaceStrategy friction = new FrictionSurfaceStrategy();
            friction.setBorderWidth(50);
            friction.setBorderHeight(50);
            rootComponent.pushStrategy(friction);
            rootComponent.Strategy.initPropertiesComponent();
            
           //Create a belt component and give it a current belt strategy 
            VisComponentGL beltComponent = new VisComponentGL();
            beltComponent.setPosition(450.0f, 350.0f);
            beltComponent.setWidth(800);
            beltComponent.setHeight(600);
            //CurrentBeltContainerStrategy currentBelt = new CurrentBeltContainerStrategy(100.0f);
            BoundedContainerStrategy currentBelt = new BoundedContainerStrategy();
            currentBelt.setNumControlPoints(8);
            currentBelt.setSplineLevels(4);
            //currentBelt.setBorderColor(borderColor);
            //currentBelt.setSelectedColor(selectedColor);
            beltComponent.pushStrategy(currentBelt);
            currentBelt.initializeDefaultShape(true);
            TranslationStrategy currentBeltTranslation = new TranslationStrategy();
            //RNTStrategy rntBelt = new RNTStrategy();
            //beltComponent.pushStrategy(rntBelt);
            beltComponent.pushStrategy(currentBeltTranslation);
            addComponent(beltComponent);

            TextureManager textures = new TextureManager();
            string[] names = new string[10];
            for (int i = 1; i <= 10; i++)
            {
                names[i-1] = @"..\..\images\00";
                if (i < 10) names[i - 1] += "0";
                names[i - 1] += i.ToString();
                names[i - 1] += ".bmp";

                textures.AddTexture(names[i - 1], TextureType.NearestFilteredTexture);
            }
            // creates n files of images and give them some basic strategies...
            int n = 15;
            for (int i = 0; i < n; i++)
            {
                VisComponentGL c = new VisComponentGL();
                c.setPosition(obtainRandomFloat(100.0f, 50.0f), obtainRandomFloat(100.0f, 50.0f), 0.0f);
                float dimension = obtainRandomFloat(150.0f, 50.0f);
                c.setWidth((uint)dimension);
                c.setHeight((uint)dimension);
                c.setRotationAngle((double)obtainRandomFloat(90.0f, 0.0f) * Math.PI/180.0);
                uint id = textures.getIdByName(names[i%10]);
                ImageStrategy imageStrategy = new ImageStrategy(id);
                c.pushStrategy(imageStrategy);
                ResizerHandleStrategy resizerHandle = new ResizerHandleStrategy();
                resizerHandle.setColor(borderColor);
                resizerHandle.setSelectedColor(selectedColor);
                resizerHandle.setHandleWidth(5.0f);
                c.pushStrategy(resizerHandle);
                BorderStrategy border = new BorderStrategy();
                border.setColor(borderColor);
                border.setSelectedColor(selectedColor);
                c.pushStrategy(border);
                LazyTossableRNTStrategy rnt = new LazyTossableRNTStrategy();
                //RNTStrategy rnt = new RNTStrategy();
                rnt.setColor(selectedColor);
                rnt.setFrictionCoefficient(1.0f);
                rnt.setStaticFrictionCoefficient(10.0f);
                c.pushStrategy(rnt);
                CurrentObserverStrategy currentObserver = new CurrentObserverStrategy();
                c.pushStrategy(currentObserver);
                c.Leaf = true;
                addComponent(c);
            }
        }
    }
}
